package com.lx.uitl;


import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @title: ConvertClass
 * @projectName jdbc-study
 * @description: 类型转换工具类
 * @author: yuanChu
 * @date: 2022/4/30  14:25
 */
public class ConvertClassUtil<T> {
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private static final String ENTITY_SRC = "entitySrc";

    /**
     * 获取资源配置文件
     *
     * @return 装好资源配置文件的Properties对象
     */
    private static Properties getProperties() {
        Properties properties = new Properties();
        InputStream is = ConvertClassUtil.class.getResourceAsStream("/properties.properties");
        try {
            properties.load(is);
            return properties;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @param clazz     要转换的类型
     * @param resultSet 传入查询到的结果集
     * @param <T>       返回的结果类型
     * @return
     * @throws SQLException           抛出的sql查询异常
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ParseException         抛出的转换异常
     */
    public static <T> List<T> ConvertTo(Class<T> clazz, ResultSet resultSet) throws SQLException, InstantiationException, IllegalAccessException, ParseException {
        //获取entity资源路径
        String src = getProperties().getProperty(ENTITY_SRC);
        List list = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();
        List<Map<String, Object>> metaMap = new ArrayList<>();
        ResultSetMetaData metaData = resultSet.getMetaData();
        while (resultSet.next()) {
            Map<String, Object> map = new HashMap<>();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                //获取无下划线的列名（要求数据库中的命名规范为word_word   不存在大写）
                String key = metaData.getColumnLabel(i).replace("_", "").toLowerCase();
                Object value = resultSet.getObject(i);

                map.put(key, value);

            }
            metaMap.add(map);
        }
        Iterator<Map<String, Object>> iterator = metaMap.stream().iterator();
        while (iterator.hasNext()) {
            //T t = clazz.newInstance();
            Object t = clazz.newInstance();
            Map<String, Object> map = iterator.next();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.getType().getTypeName().contains(src)) {
                    Object fieldClass=ConvertToFieldClass(field.getType(),map);
                    field.set(t,fieldClass);
                } else {
                    //将字段名转换成小写,可以直接从map中获取
                    String entityFieldName = field.getName().toLowerCase();
                    //获取到的属性值
                    Object value = map.get(entityFieldName);
                    field.set(t, value);
                }
            }
            list.add(t);
        }
        return list;

    }

    private static Object ConvertToFieldClass(Class<?> type, Map<String, Object> map) throws InstantiationException, IllegalAccessException {
        Object clazz = type.newInstance();
        Field[] fields = type.getDeclaredFields();
        for (Field field : fields) {
            //关闭访问控制
            field.setAccessible(true);
            String key = field.getName().toLowerCase();
            Object value = map.get(key);
            field.set(clazz,value);
        }
        return clazz;
    }
}
